/**
  save sysPara;
	donot lost after reset;
**/

/* Includes ------------------------------------------------------------------*/
#include "cmsis_os.h"
#include "backup.h"
#include "flash_if.h"
#include "string.h"
#include "common.h"

#define BACKUP_FRAME_LEN     (sizeof(BACKUP_REG_ST))
#define BACKUP_U16_LEN      (BACKUP_FRAME_LEN/2)
#define BACKUP_U32_LEN      (BACKUP_FRAME_LEN/4)
#define BACKUP_FRAME_RAM_LEN      (BACKUP_U32_LEN*4)
#define BACKUP_FRAME_NUM     (0x2000/BACKUP_U32_LEN)
#define BACKUP_HEAD         0XAA55

BACKUP_REG_ST sysBackPara;

/* 备份参数默认值 */
static void backupPara_init(void)
{
//    uint16_t i;
    BACKUP_REG_ST *ptrBackPara = &sysBackPara;

    ptrBackPara->head = BACKUP_HEAD;
    ptrBackPara->len  = BACKUP_U32_LEN;
    ptrBackPara->index = 0;
    ptrBackPara->saveFlag = 0;

}

/* 备份初始化：查询上次备份参数 */
void backup_init(void)
{
    uint16_t i, frameIndex;
    uint32_t  u32RFlashAddr;
    DWORT_UNION_ST FlashData;
    BACKUP_REG_ST *ptrBackPara = &sysBackPara;

    frameIndex = 0xFFFF;
    /* 查询最后保存的帧编号 */
    for(i = 0; i < BACKUP_FRAME_NUM; i++) {
        u32RFlashAddr = USER_FLASH_SAVE_PARA_ADDRESS + i * BACKUP_FRAME_RAM_LEN;
        FlashData.dword = (*(__IO uint32_t*)u32RFlashAddr);
        if(BACKUP_HEAD == FlashData.word[0] && BACKUP_U32_LEN == FlashData.word[1]) {
            frameIndex = i;
        }
        else if(0 == i && 0xFFFFFFFF != FlashData.dword) {
            FLASH_If_Init();
            FLASH_If_Erase(USER_FLASH_SAVE_PARA_ADDRESS);
            FLASH_If_UnInit();
        }
        else {
            break;
        }
    }

    if(frameIndex < (uint16_t)BACKUP_FRAME_NUM) { //有保存，保存数据不会出错
        u32RFlashAddr = USER_FLASH_SAVE_PARA_ADDRESS + frameIndex * BACKUP_FRAME_RAM_LEN;
        FLASH_If_Read(&u32RFlashAddr, (uint32_t*)ptrBackPara, BACKUP_U32_LEN);
			  getParaBackup();
        ptrBackPara->index++;
        ptrBackPara->saveFlag = 0;
    }
    else { //从没保存
			  ParaBackupInit();
        backupPara_init();
    }
}

/* 保存参数 */
void backup_savePara(void)
{
    static uint32_t lastSave = 0;
    uint32_t  u32WFlashAddr;
    BACKUP_REG_ST *ptrBackPara = &sysBackPara;

//    if(0 == ptrBackPara->saveFlag) {
//        lastSave = xTaskGetTickCount();
//        return;
//    }
    //if(xTaskGetTickCount() > lastSave + 6000)
		{
        if(BACKUP_FRAME_NUM == ptrBackPara->index || 0 == ptrBackPara->index) {
            FLASH_If_Init();
            FLASH_If_Erase(USER_FLASH_SAVE_PARA_ADDRESS);
            FLASH_If_UnInit();
            ptrBackPara->index = 0;
        }
        u32WFlashAddr = USER_FLASH_SAVE_PARA_ADDRESS + ptrBackPara->index * BACKUP_FRAME_RAM_LEN;
        FLASH_If_Init();
        if( FLASH_If_Write((__IO uint32_t*)&u32WFlashAddr, (uint32_t *)ptrBackPara, BACKUP_U32_LEN) == 0 ) //ture
        {
            ptrBackPara->saveFlag = 0;
        }
        else {
            lastSave = xTaskGetTickCount();
        }
        FLASH_If_UnInit();
        ptrBackPara->index++;
        lastSave = xTaskGetTickCount();
    }
}

/* 写len个uint16_t数据*/
void SetU16Backup(uint8_t addr, uint16_t *data, uint16_t len)
{
    uint16_t *sysBack = (uint16_t *)&sysBackPara;

    if((addr + len) > BACKUP_U16_LEN) {
        return;
    }
    while(len--)
    {
        if(sysBack[addr] != *data) {
            sysBackPara.saveFlag = 1;
        }
        sysBack[addr++] = *data++;
    }
}

/* 写len个uint8_t数据*/
void SetU8Backup(uint8_t addr, uint8_t *data, uint16_t len)
{
    uint16_t u16Len, u16Data;
    uint16_t *sysBack = (uint16_t *)&sysBackPara;

    u16Len = len / 2;
    if((addr + u16Len) > BACKUP_U16_LEN) {
        return;
    }
    while(u16Len--)
    {
        u16Data = *data++;
        u16Data = (u16Data << 8) + *data++;
        if(sysBack[addr] != u16Data) {
            sysBackPara.saveFlag = 1;
        }
        sysBack[addr++] = u16Data;
    }
}

/* 读len个uint16_t数据*/
void GetU16Backup(uint8_t addr, uint16_t *data, uint16_t len)
{
    uint16_t *sysBack = (uint16_t *)&sysBackPara;

    if((addr + len) > BACKUP_U16_LEN) {
        return;
    }
    while(len--)
    {
        *data++	= sysBack[addr++];
    }
}

/* 读len个uint8_t数据*/
void GetU8Backup(uint8_t addr, uint8_t *data, uint16_t len)
{
    uint16_t u16Len, u16Data;
    uint16_t *sysBack = (uint16_t *)&sysBackPara;

    u16Len = len / 2;
    if((addr + u16Len) > BACKUP_U16_LEN) {
        return;
    }
    while(u16Len--)
    {
        u16Data	= sysBack[addr++];
        *data++	= u16Data >> 8;
        *data++	= u16Data & 0x00FF;
    }
}
/* 写len个uint16_t数据*/
uint8_t SaveParaBackup(uint8_t *para)
{
    uint8_t *ptrPara = (uint8_t *)&(sysBackPara.saveBuf);
    sysBackPara.saveFlag = 1;
	  memcpy(ptrPara,(uint8_t *)para,BACK_PARA_NUM);

	  backup_savePara();
	  if(sysBackPara.saveFlag){ //保存失败

		}
		else{   //成功
			Write_Card_TcpPara(0, BACK_PARA_NUM, ptrPara);
		}
	  return sysBackPara.saveFlag;
}

void getParaBackup(void)
{
    uint8_t *tcpbuf = (uint8_t *)&(sysBackPara.saveBuf);
    Write_Card_TcpPara(0, BACK_PARA_NUM, tcpbuf);

	  printf("stm32 flash  %d\r\n",sysBackPara.index);
	  printf("DEV NetWork  IP: %d.%d.%d.%d\r\n", tcpbuf[TCP_IP_ADD], tcpbuf[TCP_IP_ADD + 1], tcpbuf[TCP_IP_ADD + 2], tcpbuf[TCP_IP_ADD + 3]);
		printf("DEV NetWork  GW: %d.%d.%d.%d\r\n", tcpbuf[TCP_GW_ADD], tcpbuf[TCP_GW_ADD + 1], tcpbuf[TCP_GW_ADD + 2], tcpbuf[TCP_GW_ADD + 3]);
		printf("DEV NetWork  MAC: %x:%x:%x:%x:%x:%x\r\n", tcpbuf[TCP_MAC_ADD], tcpbuf[TCP_MAC_ADD + 1], tcpbuf[TCP_MAC_ADD + 2], tcpbuf[TCP_MAC_ADD + 3], tcpbuf[TCP_MAC_ADD + 4], tcpbuf[TCP_MAC_ADD + 5]);
    printf("DEV NetWork  PORT: %d\r\n", (tcpbuf[TCP_PORT_ADD] << 8) + tcpbuf[TCP_PORT_ADD + 1]);
    printf("DEV Version  :V %d\r\n", CAR_VERSION);
		printf("DEV remote  IP: %d.%d.%d.%d\r\n", tcpbuf[TCP_TRAPIP_ADD], tcpbuf[TCP_TRAPIP_ADD + 1], tcpbuf[TCP_TRAPIP_ADD + 2], tcpbuf[TCP_TRAPIP_ADD + 3]);
		printf("DEV remote  PORT: %d\r\n", (tcpbuf[TCP_TRAPPORT_ADD] << 8) + tcpbuf[TCP_TRAPPORT_ADD + 1]);
}
//初始化参数
void ParaBackupInit(void)
{
	  uint8_t *tcpbuf = (uint8_t *)&(sysBackPara.saveBuf);
	  uint8_t index;
	  uint16_t crc_init;

    index = 0;
    tcpbuf[index++] = 0xBB;
    tcpbuf[index++] = 0xDD;

    tcpbuf[index++] = 192;
    tcpbuf[index++] = 168;
    #if(USE_UDP_TYPE == UDP_COMM_CLINET)
    tcpbuf[index++] = 1;
    tcpbuf[index++] = 30;
    tcpbuf[index++] = 255;
    tcpbuf[index++] = 255;
    tcpbuf[index++] = 255;
    tcpbuf[index++] = 0;

    tcpbuf[index++] = 192;
    tcpbuf[index++] = 168;
    tcpbuf[index++] = 1;
    tcpbuf[index++] = 1;
    #else
    tcpbuf[index++] = 1;
    tcpbuf[index++] = 31;
    tcpbuf[index++] = 255;
    tcpbuf[index++] = 255;
    tcpbuf[index++] = 255;
    tcpbuf[index++] = 0;

    tcpbuf[index++] = 192;
    tcpbuf[index++] = 168;
    tcpbuf[index++] = 1;
    tcpbuf[index++] = 1;
    #endif


    uint32_t ChipUniqueID[3], tmp[2];
    ChipUniqueID[0] = *(__IO uint32_t*)(0x1FFF7A10);
    ChipUniqueID[1] = *(__IO uint32_t*)(0x1FFF7A14);
    ChipUniqueID[2] = *(__IO uint32_t*)(0x1FFF7A18);

    tmp[0] = ChipUniqueID[0] << 2 ;
    tmp[1] = ((ChipUniqueID[0] >> 30) & 0x03 ) + (ChipUniqueID[1] << 2) & 0xfffffffc;
    memcpy(&tcpbuf[index], tmp, 6);
    index += 6;

    tcpbuf[index++] = TCP_RUN_PORT / 256;
    tcpbuf[index++] = TCP_RUN_PORT % 256;
    tcpbuf[index++] = CAR_VERSION / 256;
    tcpbuf[index++] = CAR_VERSION % 256;

    tcpbuf[index++] = 192;
    tcpbuf[index++] = 168;
    tcpbuf[index++] = 1;
    tcpbuf[index++] = 248;
    tcpbuf[index++] = TCP_TRAP_PORT / 256;
    tcpbuf[index++] = TCP_TRAP_PORT % 256;

	  crc_init = Common_crc16lw(tcpbuf, crc_init, (CARD_PARA_LEN - 2));
    tcpbuf[CARD_PARA_LEN - 2] = (crc_init >> 8) & 0xff;
    tcpbuf[CARD_PARA_LEN - 1] = crc_init & 0xff;

		Write_Card_TcpPara(0, CARD_PARA_LEN, tcpbuf);
    SETRegInput4(MB_TCP_IP, (uint16_t*)&tcpbuf[TCP_IP_ADD], (MB_SOFT_VERSION - MB_TCP_IP + 1));

    printf("stm32 flash NULL\r\n");
	  printf("DEV NetWork  IP: %d.%d.%d.%d\r\n", tcpbuf[TCP_IP_ADD], tcpbuf[TCP_IP_ADD + 1], tcpbuf[TCP_IP_ADD + 2], tcpbuf[TCP_IP_ADD + 3]);
		printf("DEV NetWork  GW: %d.%d.%d.%d\r\n", tcpbuf[TCP_GW_ADD], tcpbuf[TCP_GW_ADD + 1], tcpbuf[TCP_GW_ADD + 2], tcpbuf[TCP_GW_ADD + 3]);
		printf("DEV NetWork  MAC: %x:%x:%x:%x:%x:%x\r\n", tcpbuf[TCP_MAC_ADD], tcpbuf[TCP_MAC_ADD + 1], tcpbuf[TCP_MAC_ADD + 2], tcpbuf[TCP_MAC_ADD + 3], tcpbuf[TCP_MAC_ADD + 4], tcpbuf[TCP_MAC_ADD + 5]);
    printf("DEV NetWork  PORT: %d\r\n", (tcpbuf[TCP_PORT_ADD] << 8) + tcpbuf[TCP_PORT_ADD + 1]);
    printf("DEV Version  :V %d\r\n", CAR_VERSION);
		printf("DEV remote  IP: %d.%d.%d.%d\r\n", tcpbuf[TCP_TRAPIP_ADD], tcpbuf[TCP_TRAPIP_ADD + 1], tcpbuf[TCP_TRAPIP_ADD + 2], tcpbuf[TCP_TRAPIP_ADD + 3]);
		printf("DEV remote  PORT: %d\r\n", (tcpbuf[TCP_TRAPPORT_ADD] << 8) + tcpbuf[TCP_TRAPPORT_ADD + 1]);
}
